From 6d7a6ae89bd12640e863a10fc88b6678f9dc9477 Mon Sep 17 00:00:00 2001
Message-Id: <6d7a6ae89bd12640e863a10fc88b6678f9dc9477.1513518702.git.jan.steffens@gmail.com>
From: "Jan Alexander Steffens (heftig)" <jan.steffens@gmail.com>
Date: Sat, 16 Dec 2017 04:18:01 +0100
Subject: [PATCH] Make cd_color_get_blackbody_rgb_full safer

Validate arguments. If temp is divisible by 100, avoid interpolation
because it accesses beyond the data for temp == 10000.
---
 lib/colord/cd-color.c | 23 +++++++++++++++--------
 1 file changed, 15 insertions(+), 8 deletions(-)

diff --git a/lib/colord/cd-color.c b/lib/colord/cd-color.c
index 6062595187616846..9960e7ecd247a289 100644
--- a/lib/colord/cd-color.c
+++ b/lib/colord/cd-color.c
@@ -1444,33 +1444,40 @@ cd_color_get_blackbody_rgb_full (gdouble temp,
 				 CdColorBlackbodyFlags flags)
 {
 	gboolean ret = TRUE;
-	gdouble alpha;
-	gint temp_index;
+	guint temp_quot, temp_rem;
 	const CdColorRGB *blackbody_func = blackbody_data_d65modified;
 
+	g_return_val_if_fail (!isnan (temp), FALSE);
+	g_return_val_if_fail (result != NULL, FALSE);
+
 	/* use modified curve */
 	if (flags & CD_COLOR_BLACKBODY_FLAG_USE_PLANCKIAN)
 		blackbody_func = blackbody_data_d65plankian;
 
 	/* check lower bound */
 	if (temp < 1000) {
 		ret = FALSE;
 		temp = 1000;
 	}
 
 	/* check upper bound */
 	if (temp > 10000) {
 		ret = FALSE;
 		temp = 10000;
 	}
 
 	/* bilinear interpolate the blackbody data */
-	alpha = ((guint) temp % 100) / 100.0;
-	temp_index = ((guint) temp - 1000) / 100;
-	cd_color_rgb_interpolate (&blackbody_func[temp_index],
-				  &blackbody_func[temp_index + 1],
-				  alpha,
-				  result);
+	temp_quot = (guint) temp / 100;
+	temp_rem = (guint) temp % 100;
+
+	if (temp_rem == 0)
+		*result = blackbody_func[temp_quot - 10];
+	else
+		cd_color_rgb_interpolate (&blackbody_func[temp_quot - 10],
+					  &blackbody_func[temp_quot - 9],
+					  temp_rem / 100.0,
+					  result);
+
 	return ret;
 }
 
-- 
2.15.1
